package com.timothy.service;

import java.util.Random;

import eneter.messaging.diagnostic.EneterTrace;
import eneter.messaging.endpoints.stringmessages.DuplexStringMessagesFactory;
import eneter.messaging.endpoints.stringmessages.IDuplexStringMessageSender;
import eneter.messaging.endpoints.stringmessages.IDuplexStringMessagesFactory;
import eneter.messaging.endpoints.stringmessages.StringResponseReceivedEventArgs;
import eneter.messaging.endpoints.typedmessages.DuplexTypedMessagesFactory;
import eneter.messaging.endpoints.typedmessages.IDuplexTypedMessageSender;
import eneter.messaging.endpoints.typedmessages.IDuplexTypedMessagesFactory;
import eneter.messaging.endpoints.typedmessages.TypedResponseReceivedEventArgs;
import eneter.messaging.messagingsystems.messagingsystembase.IDuplexOutputChannel;
import eneter.messaging.messagingsystems.messagingsystembase.IMessagingSystemFactory;
import eneter.messaging.messagingsystems.tcpmessagingsystem.TcpMessagingSystemFactory;
import eneter.net.system.EventHandler;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;

public class CommunicationService extends Service {
	public final static String IP = "192.168.1.104";
	public final static String PORT = "9999";

	// private IDuplexTypedMessageSender<MyResponse, MyRequest> mySender;
	private IDuplexStringMessageSender mySender;

	private Handler myRefresh = new Handler();
	public String receiveMessageString;

	// final Messenger rMessenger = new Messenger(new
	// IncomingHandler());//receive message
	// List<Messenger> sMessengers = new ArrayList<Messenger>();//send message

	/*
	 * class IncomingHandler extends Handler {
	 * 
	 * @Override public void handleMessage(Message msg) { switch (msg.what) {
	 * case 0: sMessengers.add(msg.replyTo); break; case
	 * 1:sMessengers.remove(msg.replyTo); break; } } }
	 * 
	 * public void processCommand(String command){ Object obj = null; int
	 * objType = 0; //send message if( obj != null ) { for (int
	 * i=sMessengers.size()-1; i>=0; i--) { try { sMessengers.get(i).send(
	 * Message.obtain(null, objType, obj) ); } catch (RemoteException e) {
	 * sMessengers.remove(i); } } } }
	 */

	public static class MyRequest {
		public String Text;
	}

	public static class MyResponse {
		public int Length;
	}

	@Override
	public void onCreate() {
		Log.i("ServiceDemo", "CommunicationService.onCreate()...");
		super.onCreate();

		try {
			openConnection();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onStart(Intent intent, int startId) {
		Log.i("ServiceDemo", "CommunicationService.onStart()...");
		super.onStart(intent, startId);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i("ServiceDemo", "CommunicationService.onStartCommand()...");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		Log.i("ServiceDemo", "CommunicationService.onDestroy()...");
		super.onDestroy();

		mySender.detachDuplexOutputChannel();
	}

	// Binder given to clients
	private final IBinder mBinder = new CommunicationBinder();
	// Random number generator
	private final Random mGenerator = new Random();

	/**
	 * Class used for the client Binder. Because we know this service always
	 * runs in the same process as its clients, we don't need to deal with IPC.
	 */
	public class CommunicationBinder extends Binder {
		public CommunicationService getService() {
			// Return this instance of CommunicationService so clients can call
			// public methods
			return CommunicationService.this;
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	/** method for clients */
	public int getRandomNumber() {
		Log.i("ServiceDemo", "CommunicationService.getRandomNumber()...");
		return mGenerator.nextInt(100);
	}

	private void openConnection() throws Exception {
		Log.i("ServiceDemo", "CommunicationService.openConnection()...");

		// Create sender sending MyRequest and as a response receiving
		// MyResponse
		IDuplexStringMessagesFactory aSenderFactory = new DuplexStringMessagesFactory();
		mySender = aSenderFactory.createDuplexStringMessageSender();

		// Subscribe to receive response messages.
		mySender.responseReceived().subscribe(myOnResponseHandler);

		// Create TCP messaging for the communication.
		// Note: 10.0.2.2 is a special alias to the loopback (127.0.0.1)
		// on the development machine.
		IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
		IDuplexOutputChannel anOutputChannel = aMessaging
				.createDuplexOutputChannel("tcp://" + IP + ":" + PORT + "/");

		// Attach the output channel to the sender and be able to send
		// messages and receive responses.
		mySender.attachDuplexOutputChannel(anOutputChannel);
	}

	private EventHandler<StringResponseReceivedEventArgs> myOnResponseHandler = new EventHandler<StringResponseReceivedEventArgs>() {
		@Override
		public void onEvent(Object sender, StringResponseReceivedEventArgs e) {
			onResponseReceived(sender, e);
		}
	};

	private void onResponseReceived(Object sender,
			final StringResponseReceivedEventArgs e) {
		// Display the result - returned number of characters.
		// Note: Marshal displaying to the correct UI thread.
		myRefresh.post(new Runnable() {
			@Override
			public void run() {
				receiveMessageString = e.getResponseMessage();
				Log.i("ServiceDemo","CommunicationService.onResponseReceived().run()..."+ receiveMessageString);
			}
		});
	}

	// send message

	public void onSendRequest(String message) {
		// Create the request message.
		// MyRequest aRequestMsg = new MyRequest();
		// aRequestMsg.Text = myMessageTextEditText.getText().toString();

		// Send the request message.
		try {
			mySender.sendMessage(message);
		} catch (Exception err) {
			EneterTrace.error("Sending the message failed.", err);
		}
	}

	public String getReceiveMessageString() {
		return receiveMessageString;
	}

}
